package com.capgemini.fs.app.ekms.service.implementations;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Set;

import com.capgemini.fs.app.ekms.common.CommonMethods;
import com.capgemini.fs.app.ekms.common.Constants;
import com.capgemini.fs.app.ekms.model.Forum;
import com.capgemini.fs.app.ekms.model.Reply;
import com.capgemini.fs.app.ekms.model.Topic;
import com.capgemini.fs.app.ekms.model.User;
import com.capgemini.fs.app.ekms.persistence.PersistenceService;
import com.capgemini.fs.app.ekms.persistence.dao.ForumDAO;
import com.capgemini.fs.app.ekms.service.ForumService;
import com.capgemini.fs.app.ekms.service.TopicService;

public class ForumServiceImpl implements ForumService {
	PersistenceService persistenceService = null;
	TopicService topicService = null;

	public TopicService getTopicService() {
		return topicService;
	}

	public void setTopicService(TopicService topicService) {
		this.topicService = topicService;
	}

	public PersistenceService getPersistenceService() {
		return persistenceService;
	}

	public void setPersistenceService(PersistenceService persistenceService) {
		this.persistenceService = persistenceService;
	}

	public ForumDAO getForumDAO() {
		return getPersistenceService().getForumDAO();
	}

	public Forum getForumByName(String name) {
		return getForumDAO().getForumByName(name);
	}

	public List<Forum> getAllForums() {
		return getForumDAO().getAllForums();
	}

	public void createForum(Forum forum) {
		getForumDAO().addForum(forum);
	}

	public void createForum(List<Forum> forums) {
		getForumDAO().save(forums);
	}

	public void updateForum(Forum f) {
		getForumDAO().evict(f);
		Forum exsit = getForumDAO().findByPrimaryKey(Forum.class, f.getId());
		exsit.setTopics(f.getTopics());
		exsit.setStatus(f.getStatus());
		exsit.setLastUpdateDate(f.getLastUpdateDate());
		exsit.setCreateDate(f.getCreateDate());
		exsit.setCreator(f.getCreator());
		exsit.setDescription(f.getDescription());
		exsit.setName(f.getName());
		exsit.setLastModifier(f.getLastModifier());

		getForumDAO().update(exsit);
	}

	public void updateForum(List<Forum> forums) {
		for (Forum f : forums) {
			updateForum(f);
		}
	}

	public boolean isExist(String name) {
		Forum forum = getForumDAO().getForumByName(name);
		if (forum != null) {
			return true;
		}
		return false;
	}

	public Forum getForumById(Integer id) {

		return getForumDAO().findByPrimaryKey(Forum.class, id);
	}

	public Forum findForumByName(String name) {
		return getForumDAO().getForumByName(name);
	}

	public List<Forum> queryForum(String forumName, Integer status) {
		return this.getForumDAO().queryForum(forumName, status);
	}

	public void activeForum(Integer forumId, String lastModifier) {
		Forum forum = this.getForumDAO().findByPrimaryKey(Forum.class, forumId);
		forum.setStatus(Constants.FORUM_STATUS_ACTIVE);
		forum.setLastModifier(lastModifier);
		this.updateForum(forum);

	}

	public void activeForumTopic(Integer forumId, String lastModifier) {

		Forum forum = this.getForumDAO().findByPrimaryKey(Forum.class, forumId);

		Set<Topic> forumTopic = forum.getTopics();

		for (Topic topic : forumTopic) {
			topic.setStatus(Constants.TOPIC_STATUS_ACTIVE);
			topic.setLastModifier(lastModifier);
			topicService.updateTopic(topic);

		}

	}

	public void inactiveForum(Integer forumId, String lastModifier) {
		Forum forum = this.getForumDAO().findByPrimaryKey(Forum.class, forumId);

		forum.setStatus(Constants.FORUM_STATUS_INACTIVE);
		forum.setLastModifier(lastModifier);
		this.updateForum(forum);
	}

	public void inactiveForumTopic(Integer forumId, String lastModifier) {
		Forum forum = getForumDAO().findByPrimaryKey(Forum.class, forumId);
		Set<Topic> forumTopic = forum.getTopics();
		for (Topic topic : forumTopic) {
			topic.setLastModifier(lastModifier);
			topic.setStatus(Constants.TOPIC_STATUS_INACTIVE);
			getTopicService().updateTopic(topic);
		}

	}

	public List<Topic> queryForumTopics(int forumId) {
		return getForumDAO().queryForumTopics(forumId);
	}

	// Add moderator for forum

	public Integer addModerator(Integer userId, Integer forumId) {
		Integer result = null;
		User user = getPersistenceService().getUserDAO()
				.get(User.class, userId);
		Forum forum = getForumById(forumId);
		if (user == null || forum == null) {
			result = Constants.USER_OR_FORUM_NOT_EXIST_ERROR;
		} else {
			if (!isForumMember(user, forum)) {
				result = Constants.NOT_FORUM_MEMBER_ADD_ERRO;
			} else {
				if (isForumModerator(user, forum)) {
					result = Constants.MODERATOR_EXIST_ERROR;
				} else {
					forum.getModerators().add(user);
					getForumDAO().update(forum);
					result = Constants.ADD_MODERATOR_SUCC;
				}
			}
		}
		return result;
	}

	public boolean isForumMember(User user, Forum forum) {
		boolean result = false;
		Set<User> forumMembers = forum.getMembers();
		if (0 == forumMembers.size()) {
			result = false;
		} else {
			for (User forumMember : forumMembers) {
				if (forumMember.getId() == user.getId()) {
					result = true;
					break;
				} else {
					result = false;
				}
			}
		}
		return result;
	}

	public boolean isForumModerator(User user, Forum forum) {
		boolean result = false;
		Set<User> forumModerators = forum.getModerators();
		if (0 == forumModerators.size()) {
			result = false;
		} else {
			for (User forumModerator : forumModerators) {
				if (forumModerator.getId() == user.getId()) {
					result = true;
					break;
				} else {
					result = false;
				}
			}
		}
		return result;
	}

	public Integer getNewTopicCountsToday(Forum forum) {
		forum = getForumById(forum.getId());
		int count = 0;
		Set<Topic> allTopics = forum.getTopics();
		for (Topic topic : allTopics) {
			String topicDate = CommonMethods.formatDate(topic.getCreateDate());
			String nowDate = CommonMethods.formatDate(new Date());
			if (topicDate.equals(nowDate)) {
				count++;
			}
		}
		return count;
	}

	public Integer getPostCounts(Forum forum) {
		Integer postCounts=0;
		forum = getForumById(forum.getId());
		Set<Topic> allTopics = forum.getTopics();
		for (Topic topic : allTopics) {
			Set<Reply> replies = topic.getReplies();
			postCounts+=replies.size();
		}
		return postCounts;
	}

	public Topic getLastTopic(Forum forum) {
		forum=getForumDAO().get(Forum.class, forum.getId());
		Set<Topic> allTopics=forum.getTopics();
		if(0==allTopics.size()){
			return null;
		}else{
			List<Topic> topicList=new ArrayList<Topic>();
			for(Topic topic:allTopics){
				topicList.add(topic);
			}
			Collections.sort(topicList);
			Collections.reverse(topicList);
			return topicList.get(0);
		}
		
	}
	Comparator<Topic> compareByTopicCreateDate = new Comparator<Topic>() {
		public int compare(Topic t1, Topic t2) {
			return t1.getCreateDate().compareTo(t2.getCreateDate());
		}
	};

}
